#!/usr/bin/env python3
"""
分析WebSocket通信和LSP协议
"""

import subprocess
import json
import re

def analyze_websocket_details():
    """分析WebSocket连接详情"""
    print("🔌 === WebSocket通信分析 ===\n")
    
    # 从JAR中提取WebSocket相关信息
    jar_file = "lingma-jetbrains/lib/cosy-intellij-2.5.16.jar"
    
    # 搜索WebSocket相关字符串
    try:
        result = subprocess.run(['strings', jar_file], capture_output=True, text=True)
        content = result.stdout
        
        # 查找端口和URL模式
        patterns = {
            "localhost_urls": re.findall(r'(ws://localhost[:\d/]*)', content),
            "localhost_ips": re.findall(r'(ws://127\.0\.0\.1[:\d/]*)', content),
            "ports": re.findall(r'localhost:(\d+)', content),
            "websocket_paths": re.findall(r'ws://[^/]+(/[^\s"\']*)', content),
        }
        
        for category, matches in patterns.items():
            if matches:
                print(f"{category}:")
                for match in set(matches):
                    print(f"  {match}")
                print()
    
    except Exception as e:
        print(f"分析失败: {e}")

def find_default_port():
    """查找默认端口"""
    print("🔍 === 查找默认端口 ===\n")
    
    # 从类文件中搜索端口常量
    jar_file = "lingma-jetbrains/lib/cosy-intellij-2.5.16.jar"
    
    try:
        result = subprocess.run(['strings', jar_file], capture_output=True, text=True)
        content = result.stdout
        
        # 查找可能的端口号
        port_lines = []
        for line in content.split('\n'):
            # 查找包含端口号的行
            if re.search(r'\b\d{4,5}\b', line) and any(keyword in line.lower() for keyword in ['port', 'localhost', 'ws://', 'connect']):
                port_lines.append(line.strip())
        
        print("可能的端口配置:")
        for line in set(port_lines):
            if line:
                print(f"  {line}")
    
    except Exception as e:
        print(f"端口查找失败: {e}")

def analyze_lsp_protocol():
    """分析LSP协议实现"""
    print("\n📡 === LSP协议分析 ===\n")
    
    if not os.path.exists("temp_jar"):
        print("请先运行 quick_java_analysis.py 提取JAR文件")
        return
    
    # 查找LSP相关的类和接口
    lsp_files = []
    import os
    for root, dirs, files in os.walk("temp_jar"):
        for file in files:
            if 'lsp' in file.lower():
                lsp_files.append(os.path.join(root, file))
    
    print(f"找到 {len(lsp_files)} 个LSP相关文件:")
    for file in lsp_files:
        print(f"  {file}")
    
    # 分析LSP模型
    model_dir = "temp_jar/com/alibabacloud/intellij/cosy/core/lsp/model"
    if os.path.exists(model_dir):
        print(f"\nLSP模型类:")
        for root, dirs, files in os.walk(model_dir):
            for file in files:
                if file.endswith('.class'):
                    print(f"  {file}")

def extract_config_info():
    """提取配置信息"""
    print("\n⚙️ === 配置信息提取 ===\n")
    
    config_file = "temp_jar/completion/language.json"
    if os.path.exists(config_file):
        print("语言配置文件内容:")
        with open(config_file, 'r', encoding='utf-8') as f:
            config = json.load(f)
            print(json.dumps(config, indent=2))
    
    # 查找其他配置文件
    if os.path.exists("temp_jar"):
        print("\n其他配置文件:")
        for root, dirs, files in os.walk("temp_jar"):
            for file in files:
                if any(file.endswith(ext) for ext in ['.json', '.properties']):
                    filepath = os.path.join(root, file)
                    if 'config' in file.lower() or 'setting' in file.lower():
                        print(f"  {filepath}")
                        
                        try:
                            with open(filepath, 'r', encoding='utf-8') as f:
                                content = f.read()
                                # 只显示前500字符
                                print(f"    内容预览: {content[:200]}...")
                        except:
                            pass

def create_websocket_test():
    """创建WebSocket测试客户端"""
    print("\n🧪 === 创建测试客户端 ===\n")
    
    test_script = '''#!/usr/bin/env python3
"""
WebSocket测试客户端 - 连接本地Lingma服务
"""

import asyncio
import websockets
import json
import sys

class LingmaWSClient:
    def __init__(self, port=None):
        # 常见的端口
        self.possible_ports = [23456, 12345, 8080, 9999, 7777, 6666, 5555]
        if port:
            self.possible_ports.insert(0, port)
        
        self.uri = None
        self.websocket = None
    
    async def find_service(self):
        """查找Lingma服务端口"""
        print("🔍 查找Lingma WebSocket服务...")
        
        for port in self.possible_ports:
            uri = f"ws://localhost:{port}"
            print(f"尝试连接: {uri}")
            
            try:
                websocket = await websockets.connect(uri, timeout=2)
                print(f"✅ 连接成功: {uri}")
                self.uri = uri
                self.websocket = websocket
                return True
            except Exception as e:
                print(f"❌ 连接失败: {e}")
        
        print("未找到Lingma WebSocket服务")
        return False
    
    async def send_lsp_request(self, method, params=None):
        """发送LSP请求"""
        if not self.websocket:
            print("WebSocket未连接")
            return None
        
        request = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": method,
            "params": params or {}
        }
        
        print(f"📤 发送请求: {method}")
        await self.websocket.send(json.dumps(request))
        
        try:
            response = await asyncio.wait_for(self.websocket.recv(), timeout=5.0)
            print(f"📥 收到响应: {response}")
            return json.loads(response)
        except asyncio.TimeoutError:
            print("⏰ 响应超时")
            return None
    
    async def test_methods(self):
        """测试常见的LSP方法"""
        methods_to_test = [
            "initialize",
            "textDocument/completion", 
            "textDocument/didOpen",
            "chat/ask",
            "search/query",
            "$/ping",
            "$/status"
        ]
        
        for method in methods_to_test:
            response = await self.send_lsp_request(method)
            if response:
                print(f"✅ {method} 可用")
            else:
                print(f"❌ {method} 不可用")
            
            await asyncio.sleep(0.5)
    
    async def close(self):
        """关闭连接"""
        if self.websocket:
            await self.websocket.close()

async def main():
    client = LingmaWSClient()
    
    if await client.find_service():
        await client.test_methods()
    
    await client.close()

if __name__ == "__main__":
    asyncio.run(main())
'''
    
    with open('test_websocket_client.py', 'w') as f:
        f.write(test_script)
    
    print("✅ WebSocket测试客户端已创建: test_websocket_client.py")
    print("\n使用方法:")
    print("1. 确保IDEA和Lingma插件正在运行")
    print("2. 运行: python3 test_websocket_client.py")
    print("3. 观察连接和通信结果")

def analyze_go_startup():
    """分析Go程序启动"""
    print("\n🚀 === Go程序启动分析 ===\n")
    
    # 检查是否有Lingma进程在运行
    try:
        result = subprocess.run(['pgrep', '-f', 'Lingma'], capture_output=True, text=True)
        if result.stdout.strip():
            pid = result.stdout.strip()
            print(f"找到Lingma进程: PID {pid}")
            
            # 查看进程网络连接
            try:
                netstat_result = subprocess.run([
                    'netstat', '-tlnp'
                ], capture_output=True, text=True)
                
                print("\n网络监听端口:")
                for line in netstat_result.stdout.split('\n'):
                    if 'Lingma' in line or any(port in line for port in ['23456', '12345', '8080']):
                        print(f"  {line}")
            except:
                pass
            
            # 查看进程打开的文件
            try:
                lsof_result = subprocess.run([
                    'lsof', '-p', pid
                ], capture_output=True, text=True)
                
                print("\n打开的网络连接:")
                for line in lsof_result.stdout.split('\n'):
                    if 'TCP' in line or 'UDP' in line:
                        print(f"  {line}")
            except:
                pass
        else:
            print("未找到Lingma进程")
            print("请启动IntelliJ IDEA并激活通义灵码插件")
    
    except Exception as e:
        print(f"进程分析失败: {e}")

def main():
    print("=" * 60)
    print("WebSocket通信协议分析")
    print("=" * 60)
    
    analyze_websocket_details()
    find_default_port()
    analyze_lsp_protocol()
    extract_config_info()
    create_websocket_test()
    analyze_go_startup()
    
    print("\n" + "=" * 60)
    print("总结")
    print("=" * 60)
    print("发现的关键信息:")
    print("1. Java插件使用WebSocket与本地Go服务通信")
    print("2. 协议基于LSP (Language Server Protocol)")
    print("3. 通信格式: JSON-RPC 2.0")
    print("4. 连接地址: ws://localhost:<端口>")
    print("\n下一步:")
    print("1. 运行 test_websocket_client.py 测试连接")
    print("2. 分析LSP请求格式")
    print("3. 直接与Go服务通信，绕过Java加密")

if __name__ == "__main__":
    import os
    main()